package myJs

import myJs.Implicits._
import myJs.myPkg._
import myJs.myPkg.jquery._
import myJs.tool.Pojo.FilterContentData
import myJs.tool.Tool
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{Element, Event, document}
import scalatags.Text.all._

import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.JSON

/**
 * Created by yz on 11/5/2020
 */
object InterSnp {

  val tabId = "interSnp"
  val tableId = "table"
  var loadingIndex: Int = _

  @JSExport("init")
  def init = {
    initTable
    registerEvent
  }

  def tableFilterEvent = {
    Tool.clickHide

    $(document.body).on("click", s"#${tabId} .myOperate", "", (y: Element) => {
      Tool.filterContentShow(y,tabId)
    })
    $(document.body).on("click", s"#${tabId} .mySortLi", "", (y: Element) => {
      Tool.execSort(y, tabId, () => {
        refreshTable()
      })
    })
    $(document.body).on("click", s"#${tabId} .myConfirm", "", (y: Element) => {
      Tool.confirmFilter(y, tabId, () => {
        refreshTable()
      })
    })
    $(document.body).on("click", s"#${tabId} .myHide", "", (y: Element) => {
      Tool.hideFilterContent(y)
    })
    $(document.body).on("click", s"#${tabId} .myRemove", "", (y: Element) => {
      Tool.removeCondition(y, tabId, () => {
        refreshTable()
      })
    })
    $(document.body).on("click", s"#${tabId} .myRemoveSort", "", (y: Element) => {
      Tool.removeSort(y, tabId, () => {
        refreshTable()
      })
    })
  }

  def refreshTable(f: () => js.Any = () => ()) = {
    $(s"#${tabId} #${tableId}").bootstrapTable("refresh")
    f()
  }

  def showLoading = {
    loadingIndex = layer.load(0, Tool.layerOptions.copy(shade=List("0.1", "#fff")))
  }

  def onLoadSuccess: js.Function = { () =>
    layer.close(loadingIndex)
  }

  def pageChange: js.Function = (number: Int, size: Int) => {
    showLoading
  }

  def onRefreshF: js.Function = (params: js.Any) => {
    showLoading
  }

  def registerEvent = {
    tableFilterEvent

  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "bioSample" =>
      v.toString.split("\\|").map { eachV =>
        a(href := s"https://www.ncbi.nlm.nih.gov/biosample/${eachV}", cursor.pointer, target := "_blank",
          eachV
        )
      }.mkString("|")
    case _ => v
  }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case _ => v
  }

  def initFilterContent(tabId: String = "", map: SeqMap[String, String]) = {
    val textSortDatas = (List("refId", "sampleBase") ::: map.keyList.dropRight(1).drop(4)).map { fieldName =>
      FilterContentData(fieldName, map(fieldName))
    }
    val rangeSortDatas = List("position", "mutSampleNum").map { fieldName =>
      FilterContentData(fieldName, map(fieldName))
    }

    Tool.initFilterContent(textSortDatas = textSortDatas, rangeSortDatas = rangeSortDatas, parentId = s"${tabId}")
    textSortDatas ::: rangeSortDatas
  }

  def initTable = {
    val map = SeqMap(
      "refId" -> "ref_id",
      "position" -> "position",
      "sampleBase" -> "sample_base",
      "mutSampleNum" -> "mut_sample_num",
      "refBase" -> "ref_base",
      "geneDis" -> "gene_dis",
      "geneStart" -> "gene_start",
      "geneEnd" -> "gene_end",
      "geneStand" -> "gene_stand",
      "geneName" -> "gene_name",
      "bioSample" -> "BioSample")
    val allDatas = initFilterContent(tabId, map)
    val columnNames = map.keyList
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      val style = expStyle(columnName)
      val basicOptions = ColumnOptions.field(columnName).title(title).sortable(false).formatter(fmt).cellStyle(style)
      columnName match {
        case x if allDatas.map(_.fieldName).contains(x) => basicOptions.
          sortable(false).operateable(true)
        case _ => basicOptions
      }
    }
    val options = TableOptions.columns(columns.toJSArray).searchOnButton(false).filterControl(false).idField("id").
      parentIdField("pId").treeShowField("fileName").treeEnable(true).rootParentId("0").method("post").
      sidePagination("server").ajax(ajaxRequest).pageList(js.Array("10", "25", "50", "100", "all")).pagination(true).
      onPageChange(pageChange).onLoadSuccess(onLoadSuccess).onRefresh(onRefreshF)
    $(s"#${tabId} #${tableId}").bootstrapTable(options)

    Tool.refreshCheckboxView(map.tail, tabId)

    map.keyList.drop(8).foreach { x =>
      $(s"#${tabId} #${tableId}").bootstrapTable("hideColumn", x)
      $(s"#${tabId} input:checkbox[value='${x}']").attr("checked", false)
    }
  }

  def ajaxRequest: js.Function = (params: js.Dictionary[js.Any]) => {
    val url = g.jsRoutes.controllers.MutantController.getAllSnpByServer().url.toString
    val dataMap = params("data").toString.toJDS.toMap
    val queryMap = Tool.getQueryMap(tabId)
    val dataDict = (dataMap ++ queryMap).toJSDictionary
    val data = JSON.stringify(dataDict)
    Ajax.post(url = s"${url}", data = s"${data}",
      headers = Map("Content-Type" -> "application/json"),
      responseType = "application/json").map { xhr =>
      val json = xhr.responseText.toJArJDJAn
      val successF = params("success").asInstanceOf[js.Function1[js.Any, js.Any]]
      successF(json)
    }
  }

}
